package ae.pcfc.etks.online.web.controller.client.person.register;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.support.RequestContextUtils;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.ConstantsCommon.WFProcessType;
import ae.pcfc.etks.online.common.delegate.AttachmentTypeDelegate;
import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.delegate.SecretQuestionDelegate;
import ae.pcfc.etks.online.common.vo.AttachmentTypeVO;
import ae.pcfc.etks.online.common.vo.ClientPersonReqVO;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.common.vo.SCPersonVO;
import ae.pcfc.etks.online.common.vo.SecretQuestionVO;
import ae.pcfc.etks.online.common.vo.UploadDocumentVO;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.common.Constants;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.model.ClientPersonRegister;
import ae.pcfc.etks.online.web.util.SecurityUtils;

/**
 * Controller that handles all {@link ClientPersonRegister}-related requests, i.e.: all
 * requests for /client/person/register/* or user/person/update/*
 * 
 * @author Mohtisham.Salahria
 */
@Controller
@RequestMapping(ViewPath.CLIENT_PERSON_REGISTER)
public class ClientPersonRegisterController extends BaseController{

	
	private ClientRegistrationDelegate clientRegistrationDelegate;
    private SecretQuestionDelegate secretQuestionDelegate;
	
	@Resource(name="secretQuestionDelegate")
	public void setSecretQuestionDelegate(
			SecretQuestionDelegate secretQuestionDelegate) {
		this.secretQuestionDelegate = secretQuestionDelegate;
	}
	

	@Resource(name="clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}
	
	private AttachmentTypeDelegate attachmentTypeDelegate;

	@Resource(name = "attachmentTypeDelegate")
	public void setAttachmentTypeDelegate(
			AttachmentTypeDelegate attachmentTypeDelegate) {
		this.attachmentTypeDelegate = attachmentTypeDelegate;
	}
	
	private Map<String,String> propertyConstants;

	@Resource(name = "propertyConstants")
	public void setPropertyConstants(Map<String,String> propertyConstants) {
		this.propertyConstants = propertyConstants;
	}
	
	
	@ModelAttribute(ConstantsAdmin.CLIENT_PERSON_UPLOADTYPE_REQUEST_MODEL_KEY)
	public List<LabelVO> populateUploadTypeList() 
	{

		List<LabelVO> labelList = new ArrayList<LabelVO>();
		String strAttachmentTypeUser = "CPR";
		List<AttachmentTypeVO> attachmentTypeVOs = attachmentTypeDelegate.getAttachmentType(strAttachmentTypeUser);
				
		LabelVO labelVO ;
		
		for(AttachmentTypeVO attachmentTypeVO: attachmentTypeVOs)
		{
			labelVO = getMapper().map(attachmentTypeVO, LabelVO.class);
			labelList.add(labelVO);
		}
		
		return labelList;
	}
	
	@ModelAttribute(ConstantsAdmin.USER_SECRETQUESTION_REQUEST_MODEL_KEY)
	public List<LabelVO> populateSecretQuestionList() {

		

		List<LabelVO> labelList = new ArrayList<LabelVO>();

		LabelVO labelVO;
		List<SecretQuestionVO> secretQuestionVOs = secretQuestionDelegate.getSecretQuestionList();

		for(SecretQuestionVO secretQuestionVO: secretQuestionVOs)
		{
			labelVO = getMapper().map(secretQuestionVO,LabelVO.class);
			labelList.add(labelVO);

		}
		return labelList;
	}
	
	@ModelAttribute(value = ConstantsAdmin.CLIENT_PERSON_REGISTER_SUMMARY_REQUEST_MODEL_KEY)
	public SCPersonVO populateReferenceData(HttpServletRequest request,
			@RequestParam(value = "clientId", required = false) String id) {
	
		if(id != null)
		{
			String trakheesId = SecurityUtils.decrypt(id);
			SCPersonVO scPersonVO = clientRegistrationDelegate.findSCPersonByTrakheesId(trakheesId);
			
			// TODO Here we will redirect to error page
			if(scPersonVO == null )			
				return  new SCPersonVO();			
			
			return scPersonVO; 
		}
		
		return null;
		
	}
	
	/**
	 * Custom handler for displaying the form, i.e.: GET requests for
	 * /client/person/register/form.jsp
	 * @see #form(ClientPersonRegister)
	 * @see WEB-INF/jsp/client/person/register/form.jsp
	 */	
	@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(@ModelAttribute(value = ConstantsAdmin.CLIENT_PERSON_REGISTER_REQUEST_MODEL_KEY) ClientPersonRegister command) {
		
		//SysouclientRegistrationDelegate.findSCPersonByTrakheesId("2000001");
	}

	/**
	 * Custom handler for displaying the form, i.e.: POST requests for
	 * /client/person/register/form.jsp
	 * @see #form(HttpServletRequest,SessionStatus,ClientPersonRegister, BindingResult)
	 * @see WEB-INF/jsp/client/person/register/form.jsp
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/form.htm")
	public String form(
			HttpServletRequest request,
			SessionStatus status,
			@ModelAttribute(value = ConstantsAdmin.CLIENT_PERSON_REGISTER_REQUEST_MODEL_KEY) @Valid ClientPersonRegister clientPersonRegister,
			BindingResult errors)throws Exception {
		
		
			if(uploadDocuments(request, status, clientPersonRegister))
			{
				ClientPersonReqVO clientPersonReqVO = new ClientPersonReqVO();
				
				//clientPersonReqVO.setStrProcessCode(ConstantsAdmin.PROCESS_CODE_CLIENT_PERSON_REGISTRATION);
				clientPersonReqVO.setProcessCode(WFProcessType.CLIENT_PERSON_REGISTRATION);
				clientPersonReqVO.setStrProcessStep(ConstantsAdmin.PROCESS_STEP_INITIATE_CLIENT_PERSON);
				clientPersonReqVO.setApplicationDate(Calendar.getInstance().getTime());
				clientPersonReqVO.setStrWFinitatedBy(ConstantsAdmin.CLIENT_PERSON_WORK_FLOW_INITIATE);
				clientPersonReqVO.setStrWfStatus(ConstantsCommon.IN_PROGRESS);
				clientPersonReqVO.setStrStatusEn(getMessageSource().getMessage("msg.workflow.status.in.progress", null, Locale.ENGLISH));
				clientPersonReqVO.setStrStatusAr(getMessageSource().getMessage("msg.workflow.status.in.progress", null, new Locale(Constants.LOCALE_ARABIC)));
				clientPersonReqVO.setStrClientType(Constants.PERSON);
				clientPersonReqVO.setCreateDate(Calendar.getInstance().getTime());
				clientPersonReqVO.setStrStatus(Constants.ACTIVE);
				clientPersonReqVO.setStrType(Constants.PERSON);
				
				
				getMapper().map(clientPersonRegister, clientPersonReqVO);
				clientPersonReqVO.setStrPassword(SecurityUtils.hashPassword(clientPersonRegister.getStrPassword()));
				
				clientPersonReqVO.setStrTrakheesId(SecurityUtils.decrypt(request.getParameter("clientId")));
				
				String refNo = clientRegistrationDelegate.registerPerson(clientPersonReqVO);
				
				Map<String,String> paramMap = new HashMap<String,String>();
				paramMap.put(ConstantsAdmin.REFRENCE_NO, SecurityUtils.encryptQueryParam(refNo));
				
				return ViewUtils.getRedirect(ViewPath.CONFIRMATION, PageType.SHOW, paramMap);		
				
			}
			else
			{
				String[] messageArgs =new String[]{getMessageSource().getMessage("label.login.details", null,RequestContextUtils.getLocale(request))};
				errors.reject("error.file.not.selected", messageArgs, null);
				return ViewUtils.DEFAULT_VIEW;
			}	
	}
        
	
	public boolean uploadDocuments(
			HttpServletRequest request,
			SessionStatus status,
			@ModelAttribute(value = ConstantsAdmin.CLIENT_COMPANY_REGISTRATION_INFO_REQUEST_MODEL_KEY) @Valid ClientPersonRegister clientPersonRegister )
			throws Exception {
		
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		MultiValueMap<String, MultipartFile> files = multipartRequest.getMultiFileMap();
		
		boolean uploaded = false;

		if (files != null) {
		
			@SuppressWarnings("rawtypes")
			Iterator iter = files.keySet().iterator();

			while (iter.hasNext()) 
			{
				String str = (String) iter.next();
				List<MultipartFile> fileList = files.get(str);
				
				String userFolderPath = propertyConstants.get(ConstantsAdmin.UPLOAD_USER_FILES_PATH_KEY);
				
				
				for (MultipartFile mpf : fileList) 
				{
					if( !(fileList.get(0)).isEmpty() ) 
					{
						File uploadedFile = new File( userFolderPath + clientPersonRegister.getStrClientPersonNameENG()+ FilenameUtils.getName(mpf.getOriginalFilename()));
						FileOutputStream fos = new FileOutputStream(uploadedFile);
						
						fos.write(mpf.getBytes());
						fos.close();
						
						UploadDocumentVO documentVO = new UploadDocumentVO();						
						documentVO.setURL(userFolderPath + clientPersonRegister.getStrClientPersonNameENG()+ FilenameUtils.getName(mpf.getOriginalFilename()));
						documentVO.setStrUploadDocumentType(clientPersonRegister.getStrUploadDocumentType());
						
						List<UploadDocumentVO> arrDocumentVOs ;
						
						if(clientPersonRegister.getArrDocumentVOs() == null )
						{
							arrDocumentVOs = new ArrayList<UploadDocumentVO>();
						}else
							arrDocumentVOs = clientPersonRegister.getArrDocumentVOs();
							
						arrDocumentVOs.add(documentVO);
						
						clientPersonRegister.setArrDocumentVOs(arrDocumentVOs);
						
						//clientPersonRegister.setStrUploadURL(UPLOAD_FILES_TEMP_PATH + StringUtils.trimAllWhitespace(mpf.getOriginalFilename()));						
						uploaded = true;

					}
				}
			}

			// status.setComplete();

		}

		return uploaded;
	}	
			
}
